﻿using Abide_AddOn_API;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace Abide.Classes
{
    public class Theme_Manager : IThemeHost
    {
        /// <summary>
        /// Gets and returns a list of addons in the current manager.
        /// </summary>
        public List<ITheme> Themes
        {
            get;
            protected set;
        }
        /// <summary>
        /// Gets and returns a theme count.
        /// </summary>
        public int ThemeCount
        {
            get { return Themes.Count; }
        }

        public Theme_Manager()
        {
            Themes = new List<ITheme>();
        }

        /// <summary>
        /// Gets an Theme from the assembly location.
        /// The assembly should be a DLL file (*.dll)
        /// </summary>
        /// <param name="AssemblyLocation">The location of the LoadThemes assembly.</param>
        /// <returns>If the return value is null, the function failed. If it is not null, the addon from the assembly is loaded.</returns>
        internal ITheme[] LoadThemes(string AssemblyLocation)
        {
            try
            {
                //Create Variables
                List<ITheme> Themes = new List<ITheme>();
                ITheme Theme = null;
                Assembly themeAssembly = null;
                Type typeInterface = null;
                FileInfo Info = null;

                //Get FileInfo
                Info = new FileInfo(AssemblyLocation);

                //Check Extension
                if (Info.Extension == ".dll")
                {
                    //Get Assembly
                    themeAssembly = Assembly.LoadFile(AssemblyLocation);

                    foreach (Type toolType in themeAssembly.GetTypes())
                    {
                        if (toolType.IsPublic && !toolType.IsAbstract)
                        {
                            typeInterface = toolType.GetInterface(typeof(ITheme).ToString(), true);

                            if (typeInterface != null)
                            {
                                try
                                {
                                    Theme = (ITheme)Activator.CreateInstance(themeAssembly.GetType(toolType.ToString()));
                                    if (Theme != null)
                                    {
                                        Theme.Host = this;
                                        Themes.Add(Theme);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(string.Format(
                                        "Failed to load Theme: \r\n{0}\r\n------\r\nException Message: {1}",
                                      AssemblyLocation,
                                      ex.Message));
                                }
                            }
                        }
                    }
                }

                //Return
                return Themes.ToArray();
            }
            catch (Exception ex)
            {
                MessageBox.Show(string.Format(
                    "Failed to load AddOn: \r\n{0}\r\n------\r\nException Message: {1}",
                  AssemblyLocation,
                  ex.Message));
            }

            return null;
        }
        /// <summary>
        /// Adds an Theme to the list of Themes.
        /// </summary>
        /// <param name="AssemblyLocation">The assembly's location.</param>
        /// <returns>Returns true if the method succeeds.</returns>
        public ITheme[] AddThemes(string AssemblyLocation)
        {
            //Create Variables
            ITheme[] Themes = LoadThemes(AssemblyLocation);

            //Check AddOn
            string AssemblyVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            foreach (ITheme Theme in Themes)
            {
                if (Theme != null)
                {
                    this.Themes.Add(Theme);
                }
            }

            return Themes;
        }

        /// <summary>
        /// Returns data requested by the Theme
        /// </summary>
        /// <param name="Command">The command context</param>
        /// <param name="Sender">The theme that sends the command</param>
        /// <param name="Args">The arguments for the command</param>
        /// <returns></returns>
        public object SendCommand(string Command, ITheme Sender, params string[] Args)
        {
            object ReturnValue = null;

            switch (Command)
            {
                case "GetMapControl":
                    switch (MapHelper.GetVersion(Args[0]))
                    {
                        case MapVersion.Halo_2:
                            ReturnValue = new UI_Elements.Halo_2.MapControl(Args[0]);
                            break;
                        case MapVersion.Halo_2b:
                            ReturnValue = new UI_Elements.Halo_2_Beta.MapControl(Args[0]);
                            break;
                        default:
                            throw new NotImplementedException("Map type not yet supported.");
                    }
                    break;

                case "GetXboxControl":
                    ReturnValue = new UI_Elements.XboxControl();
                    break;

                case "GetOptionsForm":
                    ReturnValue = new Forms.SettingsForm(Sender.MainForm);
                    break;

                case "GetMapName":
                    switch (MapHelper.GetVersion(Args[0]))
                    {
                        case MapVersion.Halo_2:

                            break;
                        case MapVersion.Halo_2b:
                            break;
                        default:
                            throw new NotImplementedException("Map type not yet supported.");
                    }
                    break;

                case "AeroEnabled":
                    bool DesktopComposition = false;

                    if (Environment.OSVersion.Version.Major >= 6)
                    {
                        //Check for Desktop Composition.
                        Potential_Software.Win32.DwmAPI.DwmIsCompositionEnabled(out DesktopComposition);
                    }

                    ReturnValue = DesktopComposition;
                    break;
            }

            return ReturnValue;
        }
    }
}
